﻿#region [ Usings ]

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using BPC.SharePoint2010.AtoZWebPart.ToolParts;
using SP = Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint;

#endregion

namespace BPC.SharePoint2010.AtoZWebPart.AtoZWebPart
{
    [ToolboxItemAttribute(false)]
    public class AtoZWebPart : WebPart
    {
        #region [ Constants ]

        private const string FILTER_NAME = "ListFilterBy";

        #endregion

        #region [ Properties ]

        [Personalizable(PersonalizationScope.Shared), WebBrowsable(false), DisplayName("View Name"), WebDisplayName("View Name")]
        public string ViewName { get; set; }

        [Personalizable(PersonalizationScope.Shared), WebBrowsable(false), DisplayName("Field Name"), WebDisplayName("Field Name")]
        public string FieldName { get; set; }

        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true), DisplayName("Custom CSS Class"), WebDisplayName("Custom CSS Class")]
        public string CustomCSSClass { get; set; }

        public string Query
        {
            get
            {
                string res = string.Empty;
                if (Page.Request.Params[FILTER_NAME] != null)
                {
                    string filterValue = Page.Request.Params[FILTER_NAME].Trim();
                    res = GetQuery(FieldName, filterValue);
                }
                return res;
            }
        }

        #endregion

        #region [ Fields ]

        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/BPC.SharePoint2010.AtoZWebPart/AtoZWebPart/AtoZWebPartUserControl.ascx";

        private SP.XsltListViewWebPart _listview;

        #endregion

        #region [ Override ]

        /// <summary>
        /// Filter the XSLT List View Web Part by query string parameter.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            SetFieldsListView(ViewName);
            if (_listview!= null && !string.IsNullOrEmpty(Query))
            {
                SetQuerryForView();                
            }
            
            base.OnInit(e);
        }

        /// <summary>
        /// Creates user control for handling the query string (set the query string parameter)
        /// </summary>
        protected override void CreateChildControls()
        {
            AtoZWebPartUserControl control = (AtoZWebPartUserControl)Page.LoadControl(_ascxPath);            
            control.CssClass = this.CustomCSSClass;
            Controls.Add(control);
           
        }

        /// <summary>
        /// Disable filtering for columns
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (_listview != null)
            {
                _listview.DisableColumnFiltering = true;
            }
            base.OnLoad(e);
        }

        /// <summary>
        /// Extends webpart editor with 2 DDLs wich contains the views and the columns for each view.
        /// </summary>
        /// <returns></returns>
        public override EditorPartCollection CreateEditorParts()
        {
            AtoZToolPart editorPart = new AtoZToolPart();

            // The ID of the Editor part should be unique. So prefix it with the ID of the Web Part.
            editorPart.ID = this.ID + "_editorPart";

            // Create a collection of Editor Parts and add them to the Editor Part collection.
            List<EditorPart> editors = new List<EditorPart> { editorPart };
            return new EditorPartCollection(editors);
        }

        #endregion

        #region [ Public ]
                
        public void SaveChanges()
        {
            // This method sets a flag indicating that the personalization data has changed.
            // This will allow the changes to the Web Part properties from outside the Web Part class.
            this.SetPersonalizationDirty();
        }

        #endregion
       
        #region [ Private ]

        /// <summary>
        /// Set the querry for view
        /// </summary>
        /// <param name="xsltListView"></param>
        private void SetQuerryForView()
        {
            XmlDocument xml = new XmlDocument();
            xml.LoadXml(_listview.XmlDefinition);

            XmlElement viewXml = xml["View"];
            XmlNode viewQuery = viewXml.SelectSingleNode("//Query");
            XmlNode where = viewQuery.SelectSingleNode("//Where");

            if (where == null)
            {
                where = xml.CreateElement("Where");
                viewQuery.AppendChild(where);
            }
            if (where.ChildNodes.Count == 1)
            {
                where.InnerXml = string.Format("<And>{0}{1}</And>", where.FirstChild.OuterXml, Query);
            }
            else
            {
                where.InnerXml = Query;
            }
            _listview.XmlDefinition = xml.InnerXml;            
        }

        private string GetQuery(string fieldName, string filterValue)
        {
            string query = string.Empty;

            if (!string.IsNullOrEmpty(fieldName) && !string.IsNullOrEmpty(filterValue) && filterValue != "All")
            {
                if (filterValue.Equals("09"))
                {
                    query = GetQueryForNumber(fieldName);
                }
                else if (filterValue.StartsWith("A", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("B", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("C", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("D", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("E", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("F", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("G", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("H", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("I", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("J", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("K", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("L", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("M", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("N", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("O", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("P", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("Q", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("R", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("S", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("T", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("U", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("V", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("W", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("X", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("Y", StringComparison.InvariantCultureIgnoreCase) ||
                   filterValue.StartsWith("Z", StringComparison.InvariantCultureIgnoreCase))
                {
                    query = GetQueryForString(fieldName, filterValue);
                }
            }
            return query;
        }

        private string GetQueryForString(string fieldName, string filterValue)
        {
            string query = string.Empty;
            string queryTemplate = @"<BeginsWith><FieldRef Name='{0}' />
                                            <Value Type='Text'>{1}</Value>
                                            </BeginsWith>";
            if (!string.IsNullOrEmpty(fieldName) && !string.IsNullOrEmpty(filterValue))
            {
                query = string.Format(queryTemplate, fieldName, filterValue);
            }

            return query;
        }

        private string GetQueryForNumber(string fieldName)
        {
            string query = string.Empty;
            string queryTemplate = @"<Or><BeginsWith><FieldRef Name='{0}' />
                                        <Value Type='Text'>0</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{1}' /><Value Type='Text'>1</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{2}' /><Value Type='Text'>2</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{3}' /><Value Type='Text'>3</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{4}' /><Value Type='Text'>4</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{5}' /><Value Type='Text'>5</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{6}' /><Value Type='Text'>6</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{7}' /><Value Type='Text'>7</Value></BeginsWith><Or>
                                        <BeginsWith><FieldRef Name='{8}' /><Value Type='Text'>8</Value></BeginsWith>
                                        <BeginsWith><FieldRef Name='{9}' /><Value Type='Text'>9</Value></BeginsWith>
                                            </Or></Or></Or></Or></Or></Or></Or></Or></Or>";
            if (!string.IsNullOrEmpty(fieldName))
            {
                query = string.Format(queryTemplate, fieldName, fieldName, fieldName, fieldName, fieldName,
                    fieldName, fieldName, fieldName, fieldName, fieldName);
            }

            return query;
        }

        private void SetFieldsListView(string viewTitle)
        {
            var ss = SPContext.Current.ContextPageInfo;
           
            _listview = FindListViewWebPart(ViewName);
        }

        private SP.XsltListViewWebPart FindListViewWebPart(string viewName)
        {
            SP.XsltListViewWebPart listview = null;
            foreach (WebPart webPart in this.WebPartManager.WebParts)
            {
                if (webPart is SP.XsltListViewWebPart && webPart.Title.Equals(viewName))
                {
                    listview = webPart as SP.XsltListViewWebPart;
                    break;
                }
            }
            return listview;
        }

        #endregion

    }
}